#pragma once
#include<map>
#include<string>
#include<fstream>
#include<set>
#include"../Comm/log.hpp"
#include"../Comm/util.hpp"

namespace ns_model
{
    //首页展示的题目信息
    struct Info
    {
        string _id;//编号
        string _title;//标题
        string _level;//难度

        bool operator<(const Info& inf) const
        {
            return _id < inf._id;
        }
    };

    //具体的题目结构
    struct Question : public Info
    {
        unsigned int _cpu_limit;//时间限制
        unsigned int _mem_limit;//空间限制

        string _desc;//题面描述
        string _show;//预先给定的接口代码
        string _to_be_merged;//待合并的完整测试代码

    };

    // 加载题目信息
    class Model
    {
        const string ROOT = "./QuestionBank/";

        void LoadQuestionBank()
        {
            string List_path = ROOT + "List.txt";
            ifstream ifs(List_path);
            if (!ifs.is_open())
            {
                LOG(FATAL, "题库信息加载失败！");
                exit(-1);
            }

            string tmp;
            vector<string> token;
            Question qsn;
            while (std::getline(ifs, tmp))
            {
                token = ns_util::StringUtil::SplitString(tmp, " ");
                string ID = token[0];
                qsn._id = ID;
                qsn._title = token[1];
                qsn._level = token[2];
                qsn._cpu_limit = atoi(token[3].c_str());
                qsn._mem_limit = atoi(token[4].c_str());

                qsn._desc = ns_util::FileUiil::ReadFile(ROOT + ID + "/desc.txt");
                qsn._show = ns_util::FileUiil::ReadFile(ROOT + ID + "/show.cc");
                qsn._to_be_merged = ns_util::FileUiil::ReadFile(ROOT + ID + "/to_be_merged.cc");

                _lib.insert({ID, qsn});
            }

            ifs.close();

            LOG(INFO, "题库信息加载成功.");
        }
    public:
        Model()
        {
            LoadQuestionBank();
        }

        //获得题目列表
         set<Info> GetList()
        {
            LOG(INFO, "请求题目列表.");
            set<Info> List;
            for (auto& e : _lib)
            {
                Info inf = {e.second._id, e.second._title, e.second._level};
                List.insert(inf);
            }
            return List;
        }

        //获得具体题目信息
        bool GetOneQuestion(string id, Question& qsn)
        {
            auto it = _lib.find(id);
            if (it != _lib.end())
            {
                qsn = it->second;
                LOG(INFO, "请求题目成功 (%s.%s).", qsn._id.c_str(), qsn._title.c_str());
                return true;
            }
            LOG(INFO, "请求暂未录入的题目编号：%s.", id.c_str());
            return false;
        }

        //Get to_be_merged code
        string Get_to_be_merged(string id)
        {
            return _lib.find(id)->second._to_be_merged;
        }

        //Get 资源限制
        unsigned int Get_cpu_limit(string id)
        {
            return _lib.find(id)->second._cpu_limit;
        }

        unsigned int Get_mem_limit(string id)
        {
            return _lib.find(id)->second._mem_limit;
        }


    private:
        map<string, Question> _lib;
    };
}